/**************************************************************************
*Copyright (C) 2025 公司名, Inc.(Gmbh) or its affiliates.
*
*All Rights Reserved.
*
*@file bsp_key.c
*
*@par dependencies
* - bsp_key.h
*
*@author fhc | 部门 | 公司 
*
*@brief Provide the HAL APIs of Key and corresponding options.
*
*Processing flow:
*
*call directly.
*
*@version V1.0 2025-11-06
*
*@note 1 tab == 4 spaces!
*
**************************************************************************/

//******************************** Includes *********************************//
#include "bsp_key.h"                      

//******************************** Includes *********************************//

//******************************** Defines **********************************//

osThreadId_t g_key_TaskHandle = NULL;     
QueueHandle_t g_key_queue     = NULL;      /* the queue of th key  */

const osThreadAttr_t g_key_Task_attributes = {
    .name = "key_Task",
    .stack_size = 128 * 4,
    .priority = (osPriority_t) osPriorityHigh,
  };
//******************************** Defines **********************************//

//******************************** Declaring ********************************//
/**
 * @brief scan the key status .
 * 
 * Steps:
 *  1.doing the specific operations
 *  
 * @param[in] key_val										:the pointer to the status of the key  
 * 
 * @return key_status_t : Status of the function.
 * 
 * */
key_status_t key_scan(key_press_status_t* const key_val)
{
    if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0))
    {
        *key_val = KEY_PRESS;
        return KEY_OK;
    }
    else
    {
        *key_val = KEY_NOT_PRESS;
    }
    return KEY_ERRORTIMEOUT;        
}
/**
 * @brief  key_task_func for thread to run.
 * 
 * Steps:
 *  1.doing the specific operations
 *  
 * @param[in] void										
 * @return None
 * 
 * */
void key_task_func(void *argument)
{
    key_status_t       ret     =        KEY_OK;
    key_press_status_t key_val = KEY_NOT_PRESS;    
    printf("key_task_func is start \r\n"); 
	/*Create a queue capable of  containing
     10 key_press_status_t values.
    */
	g_key_queue = xQueueCreate( 10, 
                            sizeof( key_press_status_t ) );
	if( NULL == g_key_queue )
	{
		// Queue was not created and must not be used.
        printf("g_key_queue was not created\r\n");
	}
    for(;;)
    {
        ret = key_scan(&key_val);
        if( KEY_OK== ret)
        {
            if( KEY_PRESS == key_val)
            {
                xQueueSendToFront(
                    g_key_queue,
                    &key_val,
                    portMAX_DELAY);
                    printf("key Send\r\n"); 
            }
        }
        osDelay(10);       
    }
}

/**
 * @brief Determine whether the button is pressed briefly or held down for a 
 * 		  long time .
 * 
 * Steps:
 *  1.doing the specific operations
 *  
 * @param[in] key_val   : the pointer to the status of the key  
 * @param[in] key_val   : Long press time 
 * 
 * @return key_status_t : Status of the function.
 * 
 * */
key_status_t key_long_short_scan(key_press_status_t* const key_val,
                                const uint32_t time_interval )
{
    /* Variables*/
    key_press_status_t recive_key_val;
    key_status_t           recive_ret;
    uint32_t              counter_tick;    
    /* Variables*/
    //获取按键值
    recive_ret = key_scan(&recive_key_val );
    //获取按键值
    if( KEY_OK == recive_ret && KEY_PRESS == recive_key_val )
    {
        counter_tick=HAL_GetTick();
        while (( counter_tick + time_interval)>HAL_GetTick())
        {};//等一段时间之后；
        //若按键值还是保持按下就认为长按，否则认为短按
        key_scan(&recive_key_val );
        if( KEY_PRESS != recive_key_val )
        {
            // 短按
            *key_val = KEY_SHORT_PRESS;
            return KEY_OK; 
        }
        else if( KEY_PRESS == recive_key_val)
        {
            // 长按
            *key_val = KEY_LONG_PRESS;
            do{
                recive_ret = key_scan(&recive_key_val );   
            }while(KEY_OK == recive_ret);
            return KEY_OK; 
        }
    }
    return KEY_ERRORTIMEOUT;     
}
//******************************** Declaring ********************************//

